#include "Utilities.h"
#include <gl/freeglut.h>
#include "Duck.h"
#include "RailGun.h"
#include "Balloon.h"
#include <cmath>
#include "windows.h"
#include "mmsystem.h"
#include <stdlib.h>

bool declining = false;

//Prints a set of characters to the screen
void printToScreen(float x, float y, char string[]){
	glRasterPos2i((GLint)x, (GLint)y);
	for (int i=0; i<(int)strlen(string); i++)
	{
		glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, string[i]);
	}
}

//Sets the camera mode to an int 0-2 for a given duck
void setCamera(int CameraMode, Duck *pMainDuck){
	if(CameraMode == 0){
		//normal viewmode
	} 
	else if (CameraMode == 1){
		//follow duck
		double x = pMainDuck->getXLocation();
		double y = pMainDuck->getYLocation();
		double z = pMainDuck->getZLocation();
		gluLookAt(x,y,z+.5, x, y , z , 00 , 1, 0.0);
	} 
	else if (CameraMode == 2) {
		//rubber ducky itself
		double x = pMainDuck->getXLocation();
		double y = pMainDuck->getYLocation();
		double z = pMainDuck->getZLocation();
		double xGunRot = pMainDuck->xRotation;
		double yGunRot = pMainDuck->yRotation;
		gluLookAt(x+((yGunRot/720)), y+(-xGunRot/360), z-2, x,y+.1, z-2.1, 0, 10.0, 0.0);
	} 
	else if (CameraMode == 3){
		//Top view mode
		gluLookAt(0, 10, -1, 0, 0, -5, 0, 10, 0);
	}
}

//
//Draws the orthogonal projections for game statuses that need to be on the screen
//
void drawHud(int score, int mode, int cameraMode, double WindowHeight, double WindowWidth, double elapsed_time, bool gameOver, double timer){
	//display total points and display mode if under GAMEMODE
	char s[8];// = convertInt(score);
	_itoa_s(score, s, 10);
	if(mode == 3){
		glMatrixMode(GL_PROJECTION);
		glPushMatrix();
		glLoadIdentity();
		glOrtho(0, WindowWidth, 0, WindowHeight, -1.0f, 1.0f);
		glMatrixMode(GL_MODELVIEW);
		glPushMatrix();
		glLoadIdentity();
		glPushAttrib(GL_DEPTH_TEST);
		glDisable(GL_DEPTH_TEST);

		glColor4f(0,0,0.0,0.0);

		//game over display
		if(gameOver){
		printToScreen((float)(WindowWidth/2.2), (float)(WindowHeight-25), "GAME OVER");
		printToScreen((float)(WindowWidth/2.8), (float)(WindowHeight-50), "Press spacebar to start a new game");
		}

		//updatePowerBar(powerBarVal);
		static char mode[] = {"Game Mode"};
		// cameraMode = 0 | normal view
		// cameraMode = 1 | follow duck
		// cameraMode = 2 | duck's perspective
		float x = 0;
		float y = (float)WindowHeight-20;
		switch(cameraMode){
		case 0:
			printToScreen(x,y,"Normal View");
			break;
		case 1:
			printToScreen(x,y,"Follow Duck View");
			break;
		case 2:
			printToScreen(x,y,"Duck's View");
			break;
		}
		//print the score
		static char display[] = {"TOTAL SCORE"};
		printToScreen(10, (float)WindowHeight/5,display);

		printToScreen(10, (float)WindowHeight/6, s);

		//print the seconds till switching balloon locations
		timer = 10 - timer/1000;
		char timerString[8];
		_itoa_s((timer),timerString,10);
		printToScreen(10,(float)WindowHeight/8,"Seconds Remaining");
		printToScreen(10, (float)WindowHeight/11, timerString);

		glPopAttrib();
		glMatrixMode(GL_PROJECTION);
		glPopMatrix();
		glMatrixMode(GL_MODELVIEW);
		glPopMatrix();
	}
	
}

/*
//Sets the random coordinates for a balloon. Has the ability to take in 2 balloon pointers so
//that the balloons do not intersect
*/
void setRandCoords(double *pX, double *pY, double *pZ, Balloon *balloon1, Balloon *balloon2)
{
	//Variables that state whether or not the pointer is received
	int bal1 = (balloon1 != NULL) ? 1 : 0;
	int bal2 = (balloon2 != NULL) ? 1 : 0;

	do
	{
		//Hit-field calculated as a set of equations that form a pyramid-esque figure
		*pZ = rand() % 8 + 10;
		double zLim = 10 + (10*(*pZ - 10)/8);
		*pX = (rand() % (int)(zLim)) - (zLim/2);
		zLim = (*pZ - 10)/8*2;
		double zVarY = double((*pZ - 10)/8*3 + 5);
		*pY = rand() % (int)(zVarY) + zLim;

		//In order to make the x field larger
		*pX = *pX - 3 + rand() % 7;
		//z is in the neg direction
		*pZ = -*pZ;
	}
	while((bal1 == 1) && (*pZ > balloon1->getZLocation() - 1 && *pZ < balloon1->getZLocation() + 1) &&
						(*pY > balloon1->getYLocation() - 2 && *pY < balloon1->getYLocation() + 2) &&
						(*pX > balloon1->getXLocation() - 1 && *pX < balloon1->getXLocation() + 1) || 
			(bal2 == 1) && (*pZ > balloon2->getZLocation() - 1 && *pZ < balloon2->getZLocation() + 1) &&
						(*pY > balloon2->getYLocation() - 2 && *pY < balloon2->getYLocation() + 2) &&
						(*pX > balloon2->getXLocation() - 1 && *pX < balloon2->getXLocation() + 1));
}

//Gives the z equation for a balloon at z, x with radius r0, and bx as the x offset from center
double zEq(double z0, double r0, double x, double bx)
{
	return z0 + sqrt(r0*r0 - ((x-bx)*(x-bx)));
}

//Gets the starting z location of the duck due to gun rotation about x and y
double getStartingZ(double xRot, double yRot)
{
	return (2 * cos(xRot / 180 * 3.1416) * cos(abs(yRot) / 180 * 3.1416))- 4;
}

//Plays the quack sound when a balloon is hit
void playHitSound()
{
	PlaySound(TEXT("quack.wav"), NULL, SND_FILENAME | SND_ASYNC); 
	return;
}

//Draws the power bar at the right edge of the window, given the time that has elapsed, and the current power
//returs the updated power to be used in a circular fashion
double drawPowerBar(double elapsed_time, double window_width, double window_height, double currentPower, bool frozen){
	glPushMatrix();

		glViewport(0, 0, (GLsizei)window_width, (GLsizei)window_height);
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluOrtho2D(0.0f, window_width, 0.0f, window_height);

	glLoadIdentity();

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(120, window_width/window_height, 1, 40);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	glColor4f(0,0,1.0,1.0);
	//make this generic
	glTranslatef(window_width/500,0,-3);
	//if fired then the power bar is frozen
	if(!frozen){
		if(!declining){
			currentPower += elapsed_time*20;
			if(currentPower > 5){
				declining = true;
				currentPower = 5;
			}
		} else {
			currentPower -= elapsed_time*20;
			if (currentPower < -3){
				declining = false;
				currentPower = -3;
			}
		}
	}
	glRectf((GLfloat)5,(GLfloat)-3,(GLfloat)5.5,(GLfloat)currentPower);
	 glPopMatrix();
	 return currentPower;
}